PAGE 118,121
TITLE KEYBRD --- 01/10/86  KEYBOARD ADAPTER BIOS
;---- INT 16 ------------------------------------------------------------
; KEYBOARD I/O								:
;	THESE ROUTINES PROVIDE KEYBOARD SUPPORT 			:
; INPUT 								:
;	(AH)=0	READ THE NEXT ASCII CHARACTER STRUCK FROM THE KEYBOARD	:
;		RETURN THE RESULT IN (AL), SCAN CODE IN (AH)		:
;	(AH)=1	SET THE Z FLAG TO INDICATE IF AN ASCII CHARACTER IS	:
;		AVAILABLE TO BE READ.					:
;		(ZF)=1 -- NO CODE AVAILABLE				:
;		(ZF)=0 -- CODE IS AVAILABLE				:
;		IF ZF = 0, THE NEXT CHARACTER IN THE BUFFER TO BE READ	:
;		IS IN AX, AND THE ENTRY REMAINS IN THE BUFFER		:
;	(AH)=2	RETURN THE CURRENT SHIFT STATUS IN AL REGISTER		:
;		THE BIT SETTINGS FOR THIS CODE ARE INDICATED IN THE	:
;		THE EQUATES FOR @KB_FLAG				:
;	(AH)=5	PLACE ASCII CHARACTER/SCAN CODE COMBINATION IN KEYBOARD :
;		BUFFER AS IF STRUCK FROM KEYBOARD			:
;									:
;		ENTRY:	(CL) = ASCII CHARACTER				:
;			(CH) = SCAN CODE				:
;									:
;		EXIT:	(AL) = 00H = SUCCESSFUL OPERATION		:
;			(AH) = 01H = UNSUCCESSFUL - BUFFER FULL 	:
;									:
;      (AH)=10H EXTENDED READ INTERFACE FOR THE ENHANCED KEYBOARD	:
;      (AH)=11H EXTENDED ASCII STATUS FOR THE ENHANCED KEYBOARD,	:
;		OTHERWISE SAME AS FUNCTION AH=1 			:
;      (AH)=12H RETURN THE EXTENDED SHIFT STATUS IN AX REGISTER 	:
;		AL = BITS FROM @KB_FLAG, AH = BITS FOR LEFT AND RIGHT	:
;		CTL AND ALT KEYS FROM @KB_FLAG_1 AND @KB_FLAG_3 	:
;									:
;		EXIT:							:
;	   ---------------						:
;	  |7|6|5|4|3|2|1|0|	AH REGISTER				:
;	   ---------------						:
;	   | | | | | | | |						:
;	   | | | | | | | '----- LEFT CONTROL KEY IS DEPRESSED           :
;	   | | | | | | '------- LEFT ALTERNATE SHIFT KEY IS DEPRESSED   :
;	   | | | | | '--------- RIGHT CONTROL KEY IS DEPRESSED          :
;	   | | | | '----------- RIGHT ALTERNATE SHIFT KEY IS DEPRESSED  :
;	   | | | '------------- SCROLL LOCK KEY IS DEPRESSED            :
;	   | | '--------------- NUM LOCK KEY IS DEPRESSED               :
;	   | '----------------- CAPS LOCK KEY IS DEPRESSED              :
;	   '------------------- SYSTEM KEY IS DEPRESSED                 :
;									:
;	   ---------------						:
;	  |7|6|5|4|3|2|1|0|	AL REGISTER				:
;	   ---------------						:
;	   | | | | | | | |						:
;	   | | | | | | | '----- RIGHT SHIFT KEY IS DEPRESSED            :
;	   | | | | | | '------- LEFT SHIFT KEY IS DEPRESSED             :
;	   | | | | | '--------- CONTROL SHIFT KEY IS DEPRESSED          :
;	   | | | | '----------- ALTERNATE SHIFT KEY IS DEPRESSED        :
;	   | | | '------------- SCROLL LOCK STATE HAS BEEN TOGGLED      :
;	   | | '--------------- NUM LOCK STATE HAS BEEN TOGGLED         :
;	   | '----------------- CAPS LOCK STATE HAS BEEN TOGGLED        :
;	   '------------------- INSERT STATE IS ACTIVE                  :
;									:
; OUTPUT								:
;	AS NOTED ABOVE, ONLY AX AND FLAGS CHANGED			:
;	ALL OTHER REGISTERS PRESERVED					:
;------------------------------------------------------------------------

	EXTRN	DDS:NEAR
	EXTRN	RESET:NEAR
	EXTRN	BEEP:NEAR

	PUBLIC	KEYBOARD_IO_1
	PUBLIC	KB_INT_1

.XLIST
INCLUDE POSTEQU.INC
INCLUDE DSEG.INC
.LIST

CODE	SEGMENT BYTE PUBLIC
	ASSUME	CS:CODE,DS:DATA
KEYBOARD_IO_1	PROC	FAR	;
	STI			; INTERRUPTS BACK ON
	PUSH	DS		; SAVE CURRENT DS
	PUSH	BX		; SAVE BX TEMPORARILY
	PUSH	CX
	CALL	DDS		; ESTABLISH POINTER TO DATA REGION
	OR	AH,AH		; AH=0
	JZ	K1		; ASCII_READ
	DEC	AH		; AH=1
	JZ	K2		; ASCII_STATUS
	DEC	AH		; AH=2
	JZ	K3		; SHIFT_STATUS
	SUB	AH,3		; AH=5
	JZ	K500		; KEYBOARD WRITE
	SUB	AH,0BH		; AH=10
	JZ	K1E		; EXTENDED_ASCII_READ
	DEC	AH		; AH=11
	JZ	K2E		; EXTENDED_ASCII_STATUS
	DEC	AH		; AH=12
	JZ	K3E		; EXTENDED_SHIFT_STATUS
K10_EXIT:
	POP	CX
	POP	BX		; RECOVER REGISTER
	POP	DS		; RECOVER SEGMENT
	IRET			; INVALID COMMAND

;------ ASCII CHARACTER

K1E:	CALL	K1S		; GET A CHARACTER FROM THE BUFFER (EXTENDED)
	CALL	K10_E_XLAT	; ROUTINE TO XLATE FOR EXTENDED CALLS
	JMP	K10_EXIT	; GIVE IT TO THE CALLER

K1:	CALL	K1S		; GET A CHARACTER FROM THE BUFFER
	CALL	K10_S_XLAT	; ROUTINE TO XLATE FOR STANDARD CALLS
	JC	K1		; CARRY SET MEANS THROW CODE AWAY
	JMP	K10_EXIT

;------ ASCII STATUS

K2E:	CALL	K2S		; TEST FOR CHARACTER IN BUFFER (EXTENDED)
	JZ	K2B		; RETURN IF BUFFER EMPTY
	PUSHF			; SAVE ZF FROM TEST
	CALL	K10_E_XLAT	; ROUTINE TO XLATE FOR EXTENDED CALLS
	JMP	SHORT K2A	; GIVE IT TO THE CALLER

K2:	CALL	K2S		; TEST FOR CHARACTER IN BUFFER
	JZ	K2B		; RETURN IF BUFFER EMPTY
	PUSHF			; SAVE ZF FROM TEST
	CALL	K10_S_XLAT	; ROUTINE TO XLATE FOR STANDARD CALLS
	JNC	K2A		; CARRY CLEAR MEANS PASS VALID CODE
	POPF			;  INVALID CODE FOR THIS TYPE OF CALL
	CALL	K1S		;  THROW THE CHARACTER AWAY
	JMP	K2		; GO LOOK FOR NEXT CHAR, IF ANY

K2A:	POPF			; RESTORE ZF FROM TEST
K2B:	POP	CX
	POP	BX		; RECOVER REGISTER
	POP	DS		; RECOVER SEGMENT
	RET	2		; THROW AWAY FLAGS

;------ SHIFT STATUS

K3E:				; GET THE EXTENDED SHIFT STATUS FLAGS
	MOV	AH,@KB_FLAG_1	; GET SYSTEM SHIFT KEY STATUS
	AND	AH,SYS_SHIFT	; MASK ALL BUT SYS KEY BIT
	MOV	CL,5		; SHIFT THE SYSTEM KEY BIT OVER TO
	SHL	AH,CL		;  BIT 7 POSITION
	MOV	AL,@KB_FLAG_1	; GET SHIFT STATES BACK
	AND	AL,01110011B	; ELIMINATE SYS_SHIFT, HOLD_STATE, AND INS_SHIFT
	OR	AH,AL		; MERGE THE REMAINING BITS INTO AH
	MOV	AL,@KB_FLAG_3	; GET RIGHT CTL AND ALT
	AND	AL,00001100B	; ELIMINATE LC_E0 AND LC_E1
	OR	AH,AL		; OR THE SHIFT FLAGS TOGETHER
K3:	MOV	AL,@KB_FLAG	; GET THE SHIFT STATUS FLAGS
	JMP	K10_EXIT	; RETURN TO CALLER

;------ WRITE TO KEYBOARD BUFFER

K500:	PUSH	SI		; SAVE SI
	CLI
	MOV	BX,@BUFFER_TAIL ; GET THE "IN TO" POINTER TO THE BUFFER
	MOV	SI,BX		; SAVE A COPY IN CASE BUFFER NOT FULL
	CALL	K4		; BUMP THE POINTER TO SEE IF BUFFER IS FULL
	CMP	BX,@BUFFER_HEAD ; WILL THE BUFFER OVERRUN IF WE STORE THIS?
	JE	K502		;  YES - INFORM CALLER OF ERROR
	MOV	[SI],CX 	;  NO  - PUT THE ASCII/SCAN CODE INTO BUFFER
	MOV	@BUFFER_TAIL,BX ; ADJUST "IN TO" POINTER TO REFLECT CHANGE
	SUB	AL,AL		; TELL CALLER THAT OPERATION WAS SUCCESSFUL
	JMP	K504		; SUB INSTRUCTION ALSO RESETS CARRY FLAG
K502:
	MOV	AL,01H		; BUFFER FULL INDICATION
K504:
	STI
	POP	SI		; RECOVER SI
	JMP	K10_EXIT	; RETURN TO CALLER

KEYBOARD_IO_1	ENDP
PAGE
;------ READ THE KEY TO FIGURE OUT WHAT TO DO ------------------------

K1S	PROC	NEAR
	MOV	BX,@BUFFER_HEAD ; GET POINTER TO HEAD OF BUFFER
	CMP	BX,@BUFFER_TAIL ; TEST END OF BUFFER
	JNE	K1T		; IF ANYTHING IN BUFFER DONT DO INTERRUPT

	MOV	AX,09002H	; MOVE IN WAIT CODE & TYPE
	INT	15H		; PERFORM OTHER FUNCTION
K1T:				; ASCII READ
	STI			; INTERRUPTS BACK ON DURING LOOP
	NOP			; ALLOW AN INTERRUPT TO OCCUR
	CLI			; INTERRUPTS BACK OFF
	MOV	BX,@BUFFER_HEAD ; GET POINTER TO HEAD OF BUFFER
	CMP	BX,@BUFFER_TAIL ; TEST END OF BUFFER
	JE	K1T		; LOOP UNTIL SOMETHING IN BUFFER

	MOV	AX,[BX] 	; GET SCAN CODE AND ASCII CODE
	CALL	K4		; MOVE POINTER TO NEXT POSITION
	MOV	@BUFFER_HEAD,BX ; STORE VALUE IN VARIABLE
	RET			; RETURN
K1S	ENDP


;------ READ THE KEY TO SEE IF ONE IS PRESENT ------------------------

K2S	PROC	NEAR
	CLI			; INTERRUPTS OFF
	MOV	BX,@BUFFER_HEAD ; GET HEAD POINTER
	CMP	BX,@BUFFER_TAIL ; IF EQUAL (Z=1) THEN NOTHING THERE
	MOV	AX,[BX]
	STI			; INTERRUPTS BACK ON
	RET			; RETURN
K2S	ENDP


;------ ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR EXTENDED CALLS

K10_E_XLAT:
	CMP	AL,0F0h 	; IS IT ONE OF THE FILL-INs?
	JNE	K10_E_RET	;  NO, PASS IT ON
	OR	AH,AH		; AH = 0 IS SPECIAL CASE
	JZ	K10_E_RET	;  PASS THIS ON UNCHANGED
	XOR	AL,AL		;  OTHERWISE SET AL = 0
K10_E_RET:
	RET			; GO BACK


;------ ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR STANDARD CALLS

K10_S_XLAT:
	CMP	AH,0E0h 	; IS IT KEYPAD ENTER OR / ?
	JNE	K10_S2		;  NO, CONTINUE
	CMP	AL,0Dh		; KEYPAD ENTER CODE?
	JE	K10_S1		;  YES, MASSAGE A BIT
	CMP	AL,0Ah		; CTRL KEYPAD ENTER CODE?
	JE	K10_S1		;  YES, MASSAGE THE SAME
	MOV	AH,35h		;  NO, MUST BE KEYPAD /
	JMP	K10_USE 	; GIVE TO CALLER
K10_S1: MOV	AH,1Ch		; CONVERT TO COMPATIBLE OUTPUT
	JMP	K10_USE 	; GIVE TO CALLER

K10_S2: CMP	AH,84h		; IS IT ONE OF THE EXTENDED ONES?
	JA	K10_DIS 	;  YES, THROW AWAY AND GET ANOTHER CHAR

	CMP	AL,0F0h 	; IS IT ONE OF THE FILL-INs?
	JNE	K10_S3		;  NO, TRY LAST TEST
	OR	AH,AH		; AH = 0 IS SPECIAL CASE
	JZ	K10_USE 	;  PASS THIS ON UNCHANGED
	JMP	K10_DIS 	;  THROW AWAY THE REST

K10_S3: CMP	AL,0E0h 	; IS IT AN EXTENSION OF A PREVIOUS ONE?
	JNE	K10_USE 	;  NO, MUST BE A STANDARD CODE
	OR	AH,AH		; AH = 0 IS SPECIAL CASE
	JZ	K10_USE 	; JUMP IF AH = 0
	XOR	AL,AL		; CONVERT TO COMPATIBLE OUTPUT
	JMP	K10_USE 	; PASS IT ON TO CALLER

K10_USE:
	CLC			; CLEAR CARRY FLAG TO INDICATE GOOD CODE
	RET			; RETURN
K10_DIS:
	STC			; SET CARRY FLAG TO INDICATE DISCARD CODE
	RET			; RETURN
PAGE
;----------------------------------------------------------------------
;	INCREMENT BUFFER POINTER ROUTINE			      -
;----------------------------------------------------------------------

K4	PROC	NEAR
	INC	BX			; MOVE TO NEXT WORD IN LIST
	INC	BX

	CMP	BX,@BUFFER_END		; AT END OF BUFFER?
	JB	K5			; NO, CONTINUE
	MOV	BX,@BUFFER_START	; YES, RESET TO BUFFER BEGINNING
K5:	RET
K4	ENDP


;----- KEYBOARD INTERRUPT ROUTINE

KB_INT_1 PROC	FAR
	PUSH	AX		; SAVE THE STI UNTIL AFTER KEYBOARD RESET
	PUSH	BX
	PUSH	CX
	PUSH	DX
	PUSH	SI
	PUSH	DI
	PUSH	DS
	PUSH	ES
	CLD			; FORWARD DIRECTION
	CALL	DDS		; SET UP ADDRESSING
	IN	AL,PORT_A	; READ IN THE CHARACTER
	XCHG	BX,AX		; SAVE IT

;-----	RESET THE SHIFT REGISTER ON THE PLANAR IF ENABLED, OR DO NOTHING IF
;-----	IT IS DISABLED

	IN	AL,KB_CTL	; GET THE CONTROL PORT
	MOV	AH,AL		; SAVE VALUE
	OR	AL,80H		; RESET BIT FOR KEYBOARD
	OUT	KB_CTL,AL
	XCHG	AH,AL		; GET BACK ORIGINAL CONTROL
	OUT	KB_CTL,AL	; KB HAS BEEN RESET
	STI
	XCHG	AX,BX		; RESTORE DATA IN

;-----	SYSTEM HOOK  INT 15H - FUNCTION 4FH  (ON HARDWARE INTERRUPT LEVEL 9H)

	MOV	AH,04FH 	; SYSTEM INTERCEPT - KEY CODE FUNCTION
	STC			; SET CY= 1 (IN CASE OF IRET)
	INT	15H		; CASSETTE CALL   (AL)= KEY SCAN CODE
				;  RETURNS CY= 1 FOR INVALID FUNCTION
	JC	KB_INT_PC	; CONTINUE IF CARRY FLAG SET ((AL)=CODE)
	JMP	K26		; EXIT IF SYSTEM HANDLED SCAN CODE
				;  EXIT HANDLES HARDWARE EOI AND ENABLE

KB_INT_PC:
	MOV	AH,AL		; SAVE SCAN CODE IN AH ALSO

;------ TEST FOR OVERRUN SCAN CODE FROM KEYBOARD

	CMP	AL,0FFH 		; IS THIS AN OVERRUN CHAR
	JNZ	K16			; NO, TEST FOR SHIFT KEY
	JMP	K62			; BUFFER_FULL_BEEP

K16:	PUSH	CS
	POP	ES			; ESTABLISH ADDRESS OF TABLES
	MOV	BH,@KB_FLAG_3		; LOAD FLAGS FOR TESTING

TEST_E0:
	CMP	AL,MC_E0		; IS THIS THE GENERAL MARKER CODE?
	JNE	TEST_E1 		;
	OR	@KB_FLAG_3,LC_E0+KBX	; SET FLAG BIT, SET KBX, AND
	JMP	SHORT EXIT_K		; THROW AWAY THIS CODE

TEST_E1:
	CMP	AL,MC_E1		; IS THIS THE PAUSE KEY?
	JNE	NOT_HC			;
	OR	@KB_FLAG_3,LC_E1+KBX	; SET FLAG, PAUSE KEY MARKER CODE
EXIT_K: JMP	K26A			; THROW AWAY THIS CODE

NOT_HC:
	AND	AL,07FH 		; TURN OFF THE BREAK BIT
	TEST	BH,LC_E0		; LAST CODE THE E0 MARKER CODE?
	JZ	NOT_LC_E0		; JUMP IF NOT

	MOV	CX,2			; LENGTH OF SEARCH
	MOV	DI,OFFSET K6+6		; IS THIS A SHIFT KEY?
	REPNE	SCASB			; CHECK IT
	JNE	K16A			; NO, CONTINUE KEY PROCESSING
	JMP	SHORT K16B		; YES, THROW AWAY & RESET FLAG

NOT_LC_E0:
	TEST	BH,LC_E1		; LAST CODE THE E1 MARKER CODE?
	JZ	T_SYS_KEY		; JUMP IF NOT

	MOV	CX,4			; LENGTH OF SEARCH
	MOV	DI,OFFSET K6+4		; IS THIS AN ALT, CTL, OR SHIFT?
	REPNE	SCASB			; CHECK IT
	JE	EXIT_K			; THROW AWAY IF SO

	CMP	AL,NUM_KEY		; IS IT THE PAUSE KEY?
	JNE	K16B			; NO, THROW AWAY & RESET FLAG
	TEST	AH,80H			; YES, IS IT THE BREAK OF THE KEY?
	JNZ	K16B			;  YES, THROW THIS AWAY TOO
	JMP	K39P
PAGE
;------ TEST FOR SYSTEM KEY

T_SYS_KEY:
	CMP	AL,SYS_KEY		; IS IT THE SYSTEM KEY?
	JNE	K16A			; CONTINUE IF NOT

	TEST	AH,080H 		; CHECK IF THIS A BREAK CODE
	JNZ	K16C			; DO NOT TOUCH SYSTEM INDICATOR IF TRUE

	TEST	@KB_FLAG_1,SYS_SHIFT	; SEE IF IN SYSTEM KEY HELD DOWN
	JNZ	K16B			; IF YES, DON'T PROCESS SYSTEM INDICATOR

	OR	@KB_FLAG_1,SYS_SHIFT	; INDICATE SYSTEM KEY DEPRESSED
	MOV	AL,EOI			; END OF INTERRUPT COMMAND
	OUT	020H,AL 		; SEND COMMAND TO INTERRUPT CONTROL PORT
					; INTERRUPT-RETURN-NO-EOI
	MOV	AX,08500H		; FUNCTION VALUE FOR MAKE OF SYSTEM KEY
	STI				; MAKE SURE INTERRUPTS ENABLED
	INT	15H			; USER INTERRUPT
	JMP	K27			; END PROCESSING

K16B:	JMP	K26			; IGNORE SYSTEM KEY

K16C:	AND	@KB_FLAG_1,NOT SYS_SHIFT ;TURN OFF SHIFT KEY HELD DOWN
	MOV	AL,EOI			; END OF INTERRUPT COMMAND
	OUT	020H,AL 		; SEND COMMAND TO INTERRUPT CONTROL PORT
					; INTERRUPT-RETURN-NO-EOI
	MOV	AX,08501H		; FUNCTION VALUE FOR BREAK OF SYSTEM KEY
	STI				; MAKE SURE INTERRUPTS ENABLED
	INT	15H			; USER INTERRUPT
	JMP	K27			; IGNORE SYSTEM KEY

;------ TEST FOR SHIFT KEYS

K16A:	MOV	BL,@KB_FLAG		; PUT STATE FLAGS IN BL
	MOV	DI,OFFSET K6		; SHIFT KEY TABLE
	MOV	CX,K6L			; LENGTH
	REPNE	SCASB			; LOOK THROUGH THE TABLE FOR A MATCH
	MOV	AL,AH			; RECOVER SCAN CODE
	JE	K17			; JUMP IF MATCH FOUND
	JMP	K25			; IF NO MATCH, THEN SHIFT NOT FOUND

;------ SHIFT KEY FOUND

K17:	SUB	DI,OFFSET K6+1		; ADJUST PTR TO SCAN CODE MTCH
	MOV	AH,CS:K7[DI]		; GET MASK INTO AH
	MOV	CL,2			; SET UP COUNT FOR FLAG SHIFTS
	TEST	AL,80H			; TEST FOR BREAK KEY
	JZ	K17C
	JMP	K23			; JUMP IF BREAK

;------ SHIFT MAKE FOUND, DETERMINE SET OR TOGGLE

K17C:	CMP	AH,SCROLL_SHIFT
	JAE	K18			; IF SCROLL SHIFT OR ABOVE, TOGGLE KEY

;------ PLAIN SHIFT KEY, SET SHIFT ON

	OR	@KB_FLAG,AH		; TURN ON SHIFT BIT
	TEST	AH,CTL_SHIFT+ALT_SHIFT	; IS IT ALT OR CTRL ?
	JNZ	K17D			;  YES, MORE FLAGS TO SET
	JMP	K26			;  NO, INTERRUPT_RETURN
K17D:	TEST	BH,LC_E0		; IS THIS ONE OF THE NEW KEYS?
	JZ	K17E			;  NO, JUMP
	OR	@KB_FLAG_3,AH		; SET BITS FOR RIGHT CTRL, ALT
	JMP	K26			; INTERRUPT_RETURN
K17E:	SHR	AH,CL			; MOVE FLAG BITS TWO POSITIONS
	OR	@KB_FLAG_1,AH		; SET BITS FOR LEFT CTRL, ALT
	JMP	K26			; INTERRUPT_RETURN

;------ TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT

K18:					; SHIFT-TOGGLE
	TEST	BL, CTL_SHIFT		; CHECK CTL SHIFT STATE
	JZ	K18A			; JUMP IF NOT CTL STATE
	JMP	K25			; JUMP IF CTL STATE
K18A:	CMP	AL,INS_KEY		; CHECK FOR INSERT KEY
	JNE	K22			; JUMP IF NOT INSERT KEY
	TEST	BL,ALT_SHIFT		; CHECK FOR ALTERNATE SHIFT
	JZ	K18B			; JUMP IF NOT ALTERNATE SHIFT
	JMP	K25			; JUMP IF ALTERNATE SHIFT
K18B:	TEST	BH,LC_E0		; IS THIS THE NEW INSERT KEY?
	JNZ	K22			; YES, THIS ONE'S NEVER A "0"
K19:	TEST	BL,NUM_STATE		; CHECK FOR BASE STATE
	JNZ	K21			; JUMP IF NUM LOCK IS ON
	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT  ; TEST FOR SHIFT STATE
	JZ	K22			   ; JUMP IF BASE STATE
K20:
	MOV	AH,AL			; PUT SCAN CODE BACK IN AH
	JMP	K25			; NUMERAL "0", STNDRD. PROCESSING

K21:	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT  ; MIGHT BE NUMERIC
	JZ	K20			   ; IS NUMERIC, STD. PROC.

K22:					; SHIFT TOGGLE KEY HIT; PROCESS IT
	TEST	AH,@KB_FLAG_1		; IS KEY ALREADY DEPRESSED
	JZ	K22A
	JMP	K26			; JUMP IF KEY ALREADY DEPRESSED
K22A:	OR	@KB_FLAG_1,AH		; INDICATE THAT THE KEY IS DEPRESSED
	XOR	@KB_FLAG,AH		; TOGGLE THE SHIFT STATE
	CMP	AL,INS_KEY		; TEST FOR 1ST MAKE OF INSERT KEY
	JNE	K26			; JUMP IF NOT INSERT KEY
	MOV	AH,AL			; SCAN CODE IN BOTH HALVES OF AX
	JMP	K28			; FLAGS UPDATED, PROC. FOR BUFFER

;------ BREAK SHIFT FOUND

K23:					; BREAK-SHIFT-FOUND
	CMP	AH,SCROLL_SHIFT 	; IS THIS A TOGGLE KEY
	NOT	AH			; INVERT MASK
	JAE	K24			; YES, HANDLE BREAK TOGGLE
	AND	@KB_FLAG,AH		; TURN OFF SHIFT BIT
	CMP	AH,NOT CTL_SHIFT	; IS THIS ALT OR CTL?
	JA	K23D			;  NO, ALL DONE

	TEST	BH,LC_E0		; 2ND ALT OR CTL?
	JZ	K23A			; NO, HANDLE NORMALLY
	AND	@KB_FLAG_3,AH		; RESET BIT FOR RIGHT ALT OR CTL
	JMP	SHORT K23B		; CONTINUE
K23A:	SAR	AH,CL			; MOVE THE MASK BIT TWO POSITIONS
	AND	@KB_FLAG_1,AH		; RESET BIT FOR LEFT ALT OR CTL
K23B:	MOV	AH,AL			; SAVE SCAN CODE
	MOV	AL,@KB_FLAG_3		; GET RIGHT ALT & CTRL FLAGS
	SHR	AL,CL			; MOVE TO BITS 1 & 0
	OR	AL,@KB_FLAG_1		; PUT IN LEFT ALT & CTL FLAGS
	SHL	AL,CL			; MOVE BACK TO BITS 3 & 2
	AND	AL,ALT_SHIFT+CTL_SHIFT	; FILTER OUT OTHER GARBAGE
	OR	@KB_FLAG,AL		; PUT RESULT IN THE REAL FLAGS
	MOV	AL,AH			; RECOVER SAVED SCAN CODE

K23D:	CMP	AL,ALT_KEY+80H		; IS THIS ALTERNATE SHIFT RELEASE
	JNE	K26			; INTERRUPT_RETURN

;------ ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER

	MOV	AL,@ALT_INPUT
	MOV	AH,0			; SCAN CODE OF 0
	MOV	@ALT_INPUT,AH		; ZERO OUT THE FIELD
	CMP	AL,0			; WAS THE INPUT=0
	JE	K26			; INTERRUPT_RETURN
	JMP	K61			; IT WASN'T, SO PUT IN BUFFER

K24:					; BREAK-TOGGLE
	AND	@KB_FLAG_1,AH		; INDICATE NO LONGER DEPRESSED
	JMP	SHORT K26		; INTERRUPT_RETURN

;------ TEST FOR HOLD STATE
					; AL, AH = SCAN CODE
K25:					; NO-SHIFT-FOUND
	CMP	AL,80H			; TEST FOR BREAK KEY
	JAE	K26			; NOTHING FOR BREAK CHARS FROM HERE ON
	TEST	@KB_FLAG_1,HOLD_STATE	; ARE WE IN HOLD STATE
	JZ	K28			; BRANCH AROUND TEST IF NOT
	CMP	AL,NUM_KEY
	JE	K26			; CAN'T END HOLD ON NUM_LOCK
	AND	@KB_FLAG_1,NOT HOLD_STATE	; TURN OFF THE HOLD STATE BIT

K26:
	AND	@KB_FLAG_3,NOT LC_E0+LC_E1   ; RESET LAST CHAR H.C. FLAG

K26A:					; INTERRUPT-RETURN
	CLI				; TURN OFF INTERRUPTS
	MOV	AL,EOI			; END OF INTERRUPT COMMAND
	OUT	020H,AL 		; SEND COMMAND TO INTERRUPT CONTROL PORT

K27:					; INTERRUPT-RETURN-NO-EOI
	POP	ES			; RESTORE REGISTERS
	POP	DS
	POP	DI
	POP	SI
	POP	DX
	POP	CX
	POP	BX
	POP	AX
	IRET				; RETURN, INTERRUPTS BACK ON
					;  WITH FLAG CHANGE
PAGE
;------ NOT IN HOLD STATE
					; AL, AH = SCAN CODE (ALL MAKES)
K28:					; NO-HOLD-STATE
	CMP	AL,88			; TEST FOR OUT-OF-RANGE SCAN CODES
	JA	K26			; IGNORE IF OUT-OF-RANGE

	TEST	BL,ALT_SHIFT		; ARE WE IN ALTERNATE SHIFT?
	JZ	K28A			; JUMP IF NOT ALTERNATE

	TEST	BH,KBX			; IS THIS THE ENHANCED KEYBOARD?
	JZ	K29			; NO, ALT STATE IS REAL

	TEST	@KB_FLAG_1,SYS_SHIFT	; YES, IS SYSREQ KEY DOWN?
	JZ	K29			;  NO, ALT STATE IS REAL
K28A:	JMP	K38			;  YES, THIS IS PHONY ALT STATE
					;	DUE TO PRESSING SYSREQ

;------ TEST FOR RESET KEY SEQUENCE (CTL ALT DEL)

K29:					; TEST-RESET
	TEST	BL,CTL_SHIFT		; ARE WE IN CONTROL SHIFT ALSO?
	JZ	K31			; NO_RESET
	CMP	AL,DEL_KEY		; SHIFT STATE IS THERE, TEST KEY
	JNE	K31			; NO_RESET

;------ CTL-ALT-DEL HAS BEEN FOUND, DO I/O CLEANUP

	MOV	@RESET_FLAG,1234H	; SET FLAG FOR RESET FUNCTION
	AND	WORD PTR @KB_FLAG_3,KBX ; CLEAR ALL FLAG BITS EXCEPT KBX
	JMP	RESET			; JUMP TO POWER ON DIAGNOSTICS

;------ ALT-INPUT-TABLE
K30	LABEL	BYTE
	DB	82,79,80,81,75
	DB	76,77,71,72,73		; 10 NUMBERS ON KEYPAD
;------ SUPER-SHIFT-TABLE
	DB	16,17,18,19,20,21	; A-Z TYPEWRITER CHARS
	DB	22,23,24,25,30,31
	DB	32,33,34,35,36,37
	DB	38,44,45,46,47,48
	DB	49,50

;------ IN ALTERNATE SHIFT, RESET NOT FOUND

K31:					; NO-RESET
	CMP	AL,57			; TEST FOR SPACE KEY
	JNE	K311			; NOT THERE
	MOV	AL,' '                  ; SET SPACE CHAR
	JMP	K57			; BUFFER_FILL
K311:
	CMP	AL,15			; TEST FOR TAB KEY
	JNE	K312			; NOT THERE
	MOV	AX,0A500h		; SET SPECIAL CODE FOR ALT-TAB
	JMP	K57			; BUFFER_FILL
K312:
	CMP	AL,74			; TEST FOR KEYPAD -
	JE	K37B			; GO PROCESS
	CMP	AL,78			; TEST FOR KEYPAD +
	JE	K37B			; GO PROCESS

;------ LOOK FOR KEY PAD ENTRY

K32:					; ALT-KEY-PAD
	MOV	DI,OFFSET K30		; ALT-INPUT-TABLE
	MOV	CX,10			; LOOK FOR ENTRY USING KEYPAD
	REPNE	SCASB			; LOOK FOR MATCH
	JNE	K33			; NO_ALT_KEYPAD
	TEST	BH,LC_E0		; IS THIS ONE OF THE NEW KEYS?
	JNZ	K37C			;  YES, JUMP, NOT NUMPAD KEY
	SUB	DI,OFFSET K30+1 	; DI NOW HAS ENTRY VALUE
	MOV	AL,@ALT_INPUT		; GET THE CURRENT BYTE
	MOV	AH,10			; MULTIPLY BY 10
	MUL	AH
	ADD	AX,DI			; ADD IN THE LATEST ENTRY
	MOV	@ALT_INPUT,AL		; STORE IT AWAY
K32A:	JMP	K26			; THROW AWAY THAT KEYSTROKE

;------ LOOK FOR SUPERSHIFT ENTRY

K33:					; NO-ALT-KEYPAD
	MOV	@ALT_INPUT,0		; ZERO ANY PREVIOUS ENTRY INTO INPUT
	MOV	CX,26			; (DI),(ES) ALREADY POINTING
	REPNE	SCASB			; LOOK FOR MATCH IN ALPHABET
	JE	K37A			; MATCH FOUND, GO FILL THE BUFFER

;------ LOOK FOR TOP ROW OF ALTERNATE SHIFT

K34:					; ALT-TOP-ROW
	CMP	AL,2			; KEY WITH '1' ON IT
	JB	K37B			; MUST BE ESCAPE
	CMP	AL,13			; IS IT IN THE REGION
	JA	K35			;  NO, ALT-SOMETHING ELSE
	ADD	AH,118			; CONVERT PSEUDO SCAN CODE TO RANGE
	JMP	SHORT K37A		; GO FILL THE BUFFER

;------ TRANSLATE ALTERNATE SHIFT PSEUDO SCAN CODES

K35:					; ALT-FUNCTION
	CMP	AL,F11_M		; IS IT F11?
	JB	K35A			;  NO, BRANCH
	CMP	AL,F12_M		; IS IT F12?
	JA	K35A			;  NO, BRANCH
	ADD	AH,52			; CONVERT TO PSEUDO SCAN CODE
	JMP	SHORT K37A		; GO FILL THE BUFFER

K35A:	TEST	BH,LC_E0		; DO WE HAVE ONE OF THE NEW KEYS?
	JZ	K37			;  NO, JUMP
	CMP	AL,28			; TEST FOR KEYPAD ENTER
	JNZ	K35B			; NOT THERE
	MOV	AX,0A600h		; SPECIAL CODE
	JMP	K57			; BUFFER FILL
K35B:	CMP	AL,83			; TEST FOR DELETE KEY
	JE	K37C			; HANDLE WITH OTHER EDIT KEYS
	CMP	AL,53			; TEST FOR KEYPAD /
	JNE	K32A			; HANDLE WITH OTHER EDIT KEYS
	MOV	AX,0A400h		; SPECIAL CODE
	JMP	K57			; BUFFER FILL

K37:	CMP	AL,59			; TEST FOR FUNCTION KEYS (F1)
	JB	K37B			;  NO FN, HANDLE W/OTHER EXTENDED
	CMP	AL,68			; IN KEYPAD REGION?
					; OR NUMLOCK, SCROLLOCK?
	JA	K32A			; IF SO, IGNORE
	ADD	AH,45			; CONVERT TO PSEUDO SCAN CODE

K37A:	MOV	AL,0			; ASCII CODE OF ZERO
	JMP	K57			; PUT IT IN THE BUFFER

K37B:	MOV	AL,0F0h 		; USE SPECIAL ASCII CODE
	JMP	K57			; PUT IT IN THE BUFFER

K37C:	ADD	AL,80			; CONVERT SCAN CODE (EDIT KEYS)
	MOV	AH,AL			; (SCAN CODE NOT IN AH FOR INSERT)
	JMP	K37A			; PUT IT IN THE BUFFER

;------ NOT IN ALTERNATE SHIFT

K38:					; NOT-ALT-SHIFT
					; BL STILL HAS SHIFT FLAGS
	TEST	BL,CTL_SHIFT		; ARE WE IN CONTROL SHIFT?
	JNZ	K38A			;  YES, START PROCESSING
	JMP	K44			; NOT-CTL-SHIFT

;------ CONTROL SHIFT, TEST SPECIAL CHARACTERS

;------ TEST FOR BREAK

K38A:	CMP	AL,SCROLL_KEY		; TEST FOR BREAK
	JNE	K39			; NO-BREAK
	TEST	BH,KBX			; IS THIS THE ENHANCED KEYBOARD?
	JZ	K38B			;  NO, BREAK IS VALID
	TEST	BH,LC_E0		;  YES, WAS LAST CODE AN E0?
	JZ	K39			;  NO-BREAK, TEST FOR PAUSE

K38B:	MOV	BX,@BUFFER_HEAD 	; RESET BUFFER TO EMPTY
	MOV	@BUFFER_TAIL,BX
	MOV	@BIOS_BREAK,80H 	; TURN ON @BIOS_BREAK BIT
	INT	1BH			; BREAK INTERRUPT VECTOR
	SUB	AX,AX			; PUT OUT DUMMY CHARACTER
	JMP	K57			; BUFFER_FILL

;-------- TEST FOR PAUSE

K39:					; NO_BREAK
	TEST	BH,KBX			; IS THIS THE ENHANCED KEYBOARD?
	JNZ	K41			; YES, THEN THIS CAN'T BE PAUSE
	CMP	AL,NUM_KEY		; LOOK FOR PAUSE KEY
	JNE	K41			; NO-PAUSE
K39P:	OR	@KB_FLAG_1,HOLD_STATE	; TURN ON THE HOLD FLAG
	MOV	AL,EOI			; END OF INTERRUPT TO CONTROL PORT
	OUT	020H,AL 		; ALLOW FURTHER KEYSTROKE INTS

;------ DURING PAUSE INTERVAL, TURN CRT BACK ON

	CMP	@CRT_MODE,7		; IS THIS BLACK AND WHITE CARD
	JE	K40			; YES, NOTHING TO DO
	MOV	DX,03D8H		; PORT FOR COLOR CARD
	MOV	AL,@CRT_MODE_SET	; GET THE VALUE OF THE CURRENT MODE
	OUT	DX,AL			; SET THE CRT MODE, SO THAT CRT IS ON
K40:					; PAUSE-LOOP
	TEST	@KB_FLAG_1,HOLD_STATE
	JNZ	K40			; LOOP UNTIL FLAG TURNED OFF
	JMP	K27			; INTERRUPT_RETURN_NO_EOI

;------ TEST SPECIAL CASE KEY 55

K41:					; NO-PAUSE
	CMP	AL,55			; TEST FOR */PRTSC KEY
	JNE	K42			; NOT-KEY-55
	TEST	BH,KBX			; IS THIS THE ENHANCED KEYBOARD?
	JZ	K41A			;  NO, CTL-PRTSC IS VALID
	TEST	BH,LC_E0		;  YES, WAS LAST CODE AN E0?
	JZ	K42B			;  NO, TRANSLATE TO A FUNCTION
K41A:	MOV	AX,114*256		; START/STOP PRINTING SWITCH
	JMP	K57			; BUFFER_FILL

;------ SET UP TO TRANSLATE CONTROL SHIFT

K42:					; NOT-KEY-55
	CMP	AL,15			; IS IT THE TAB KEY?
	JE	K42B			;  YES, XLATE TO FUNCTION CODE
	CMP	AL,53			; IS IT THE / KEY?
	JNE	K42A			;  NO, NO MORE SPECIAL CASES
	TEST	BH,LC_E0		;  YES, IS IT FROM THE KEYPAD?
	JZ	K42A			;   NO, JUST TRANSLATE
	MOV	AX,09500h		;   YES, SPECIAL CODE FOR THIS ONE
	JMP	K57			;   BUFFER FILL

K42A:	MOV	BX,OFFSET K8		; SET UP TO TRANSLATE CTL
	CMP	AL,59			; IS IT IN CHARACTER TABLE?
	JB	K45F			;  YES, GO TRANSLATE CHAR
K42B:	MOV	BX,OFFSET K8		; SET UP TO TRANSLATE CTL
	JMP	K64			;  NO, GO TRANSLATE_SCAN

;------ NOT IN CONTROL SHIFT

K44:	CMP	AL,55			; PRINT SCREEN KEY
	JNE	K45			; NOT-PRINT-SCREEN
	TEST	BH,KBX			; IS THIS ENHANCED KEYBOARD?
	JZ	K44A			;  NO, TEST FOR SHIFT STATE
	TEST	BH,LC_E0		;  YES, LAST CODE A MARKER?
	JNZ	K44B			;   YES, IS PRINT SCREEN
	JMP	SHORT K45C		;   NO, XLATE TO "*" CHARACTER
K44A:	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT   ;NOT 101 KBD, SHIFT KEY DOWN?
	JZ	K45C			;   ; NO, XLATE TO "*" CHARACTER

;------ ISSUE INTERRUPT TO INDICATE PRINT SCREEN FUNCTION
K44B:	MOV	AL,EOI			; END OF CURRENT INTERRUPT
	OUT	020H,AL 		;  SO FURTHER THINGS CAN HAPPEN
	INT	05H			; ISSUE PRINT SCREEN INTERRUPT
	AND	@KB_FLAG_3,NOT LC_E0+LC_E1 ;ZERO OUT THESE FLAGS
	JMP	K27			; GO BACK WITHOUT EOI OCCURRING


;------ HANDLE THE IN-CORE KEYS
K45:					; NOT-PRINT-SCREEN
	CMP	AL,58			; TEST FOR IN-CORE AREA
	JA	K46			; JUMP IF NOT

	CMP	AL,53			; IS THIS THE "/" KEY?
	JNE	K45A			;  NO, JUMP
	TEST	BH,LC_E0		; WAS LAST CODE THE MARKER?
	JNZ	K45C			;  YES, TRANSLATE TO CHARACTER

K45A:	MOV	CX,26			; LENGTH OF SEARCH
	MOV	DI,OFFSET K30+10	; POINT TO TABLE OF A-Z CHARS
	REPNE	SCASB			; IS THIS A LETTER KEY?
	JNE	K45B			;  NO, SYMBOL KEY

	TEST	BL,CAPS_STATE		; ARE WE IN CAPS LOCK?
	JNZ	K45D			; TEST FOR SURE
K45B:	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
	JNZ	K45E			  ; YES, UPPERCASE
					  ; NO, LOWERCASE
K45C:	MOV	BX,OFFSET K10		; TRANSLATE TO LOWERCASE LETTERS
	JMP	SHORT K56
K45D:					; ALMOST-CAPS-STATE
	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT ; CL ON. IS SHIFT ON, TOO?
	JNZ	K45C			; SHIFTED TEMP OUT OF CAPS STATE
K45E:	MOV	BX,OFFSET K11		; TRANSLATE TO UPPERCASE LETTERS
K45F:	JMP	SHORT K56


;------ TEST FOR KEYS F1 - F10
K46:					; NOT IN-CORE AREA
	CMP	AL,68			; TEST FOR F1 - F10
	JA	K47			; JUMP IF NOT
	JMP	SHORT K53		; YES, GO DO FN KEY PROCESS


;------ HANDLE THE NUMERIC PAD KEYS

K47:					; NOT F1 - F10
	CMP	AL,83			; TEST FOR NUMERIC PAD KEYS
	JA	K52			; JUMP IF NOT

;------ KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
K48:	CMP	AL,74			; SPECIAL CASE FOR MINUS
	JE	K45E			; GO TRANSLATE
	CMP	AL,78			; SPECIAL CASE FOR PLUS
	JE	K45E			; GO TRANSLATE
	TEST	BH,LC_E0		; IS THIS ONE OF THE NEW KEYS?
	JNZ	K49			;  YES, TRANSLATE TO BASE STATE

	TEST	BL,NUM_STATE		; ARE WE IN NUM LOCK?
	JNZ	K50			; TEST FOR SURE
	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE
	JNZ	K51			  ; IF SHIFTED, REALLY NUM STATE

;------ BASE CASE FOR KEYPAD
K49:	CMP	AL,76			; SPECIAL CASE FOR BASE STATE 5
	JNE	K49A			; CONTINUE IF NOT KEYPAD 5
	MOV	AL,0F0h 		; SPECIAL ASCII CODE
	JMP	K57			; BUFFER FILL
K49A:	MOV	BX,OFFSET K10		; BASE CASE TABLE
	JMP	SHORT K64		; CONVERT TO PSEUDO SCAN

;------ MIGHT BE NUM LOCK, TEST SHIFT STATUS
K50:	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT	; ALMOST-NUM-STATE
	JNZ	K49			; SHIFTED TEMP OUT OF NUM STATE
K51:	JMP	SHORT K45E		; REALLY_NUM_STATE


;------ TEST FOR THE NEW KEY ON WT KEYBOARDS

K52:					; NOT A NUMPAD KEY
	CMP	AL,86			; IS IT THE NEW WT KEY?
	JNE	K53			; JUMP IF NOT
	JMP	SHORT K45B		; HANDLE WITH REST OF LETTER KEYS


;------ MUST BE F11 OR F12
					; F1 - F10 COME HERE, TOO
K53:	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT  ; TEST SHIFT STATE
	JZ	K49			   ; JUMP, LOWERCASE PSEUDO SC'S

	MOV	BX,OFFSET K11		; UPPERCASE PSEUDO SCAN CODES
	JMP	SHORT K64		; TRANSLATE_SCAN

;------ TRANSLATE THE CHARACTER

K56:					; TRANSLATE-CHAR
	DEC	AL			; CONVERT ORIGIN
	XLAT	CS:K11			; CONVERT THE SCAN CODE TO ASCII
	TEST	@KB_FLAG_3,LC_E0	; IS THIS A NEW KEY?
	JZ	K57			;  NO, GO FILL BUFFER
	MOV	AH,MC_E0		;  YES, PUT SPECIAL MARKER IN AH
	JMP	SHORT K57		; PUT IT INTO THE BUFFER

;-----	TRANSLATE SCAN FOR PSEUDO SCAN CODES

K64:					; TRANSLATE-SCAN-ORGD
	DEC	AL			; CONVERT ORIGIN
	XLAT	CS:K8			; CTL TABLE SCAN
	MOV	AH,AL			; PUT VALUE INTO AH
	MOV	AL,0			; ZERO ASCII CODE
	TEST	@KB_FLAG_3,LC_E0	; IS THIS A NEW KEY?
	JZ	K57			;  NO, GO FILL BUFFER
	MOV	AL,MC_E0		;  YES, PUT SPECIAL MARKER IN AL

;------ PUT CHARACTER INTO BUFFER

K57:					; BUFFER_FILL
	CMP	AL,-1			; IS THIS AN IGNORE CHAR
	JE	K59			; YES, DO NOTHING WITH IT
	CMP	AH,-1			; LOOK FOR -1 PSEUDO SCAN
	JNE	K61			; NEAR_INTERRUPT_RETURN

K59:					; NEAR-INTERRUPT-RETURN
	JMP	K26			; INTERRUPT_RETURN

K61:
	CLI				; TURN OFF INTERRUPTS
	MOV	BX,@BUFFER_TAIL 	; GET THE END POINTER TO THE BUFFER
	MOV	SI,BX			; SAVE THE VALUE
	CALL	K4			; ADVANCE THE TAIL
	CMP	BX,@BUFFER_HEAD 	; HAS THE BUFFER WRAPPED AROUND
	JE	K62			; BUFFER_FULL_BEEP
	MOV	[SI],AX 		; STORE THE VALUE
	MOV	@BUFFER_TAIL,BX 	; MOVE THE POINTER UP
	MOV	AL,EOI			; END OF INTERRUPT COMMAND
	OUT	20H,AL			; SEND COMMAND TO INTERRUPT CONTROL PORT
	MOV	AX,09102H		; MOVE IN POST CODE & TYPE
	INT	15H			; PERFORM OTHER FUNCTION
	AND	@KB_FLAG_3,NOT LC_E0+LC_E1 ; RESET LAST CHAR H.C. FLAG
	JMP	K27			; INTERRUPT_RETURN

;------ BUFFER IS FULL SOUND THE BEEPER

K62:
	MOV	AL,EOI			; ENABLE INTERRUPT CONTROLLER CHIP
	OUT	INTA00,AL		;
	MOV	CX,678			; DIVISOR FOR 1760 HZ
	MOV	BL,4			; SHORT BEEP COUNT (1/16 + 1/64 DELAY)
	CALL	BEEP			; GO TO COMMON BEEP HANDLER
	JMP	K27			; EXIT

KB_INT_1	ENDP
PAGE
;---------------------------------------------------------------------
;	KEY IDENTIFICATION SCAN TABLES				     -
;---------------------------------------------------------------------

;--------------  TABLE OF SHIFT KEYS AND MASK VALUES
;------ KEY_TABLE
K6	LABEL	BYTE
	DB	INS_KEY 		; INSERT KEY
	DB	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
	DB	LEFT_KEY,RIGHT_KEY
K6L	EQU	$-K6

;------ MASK_TABLE
K7	LABEL	BYTE
	DB	INS_SHIFT		; INSERT MODE SHIFT
	DB	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
	DB	LEFT_SHIFT,RIGHT_SHIFT

;----------------------  TABLES FOR CTRL CASE  -----------------------

K8	LABEL	BYTE			;-------- CHARACTERS ---------
	DB	27,-1,00,-1,-1,-1	; Esc, 1, 2, 3, 4, 5
	DB	30,-1,-1,-1,-1,31	; 6, 7, 8, 9, 0, -
	DB	-1,127,148,17,23,5	; =, Bksp, Tab, Q, W, E
	DB	18,20,25,21,09,15	; R, T, Y, U, I, O
	DB	16,27,29,10,-1,01	; P, [,], Enter, Ctrl, A
	DB	19,04,06,07,08,10	; S, D, F, G, H, J
	DB	11,12,-1,-1,-1,-1	; K, L, ;, ', ', LShift
	DB	28,26,24,03,22,02	; Bkslash, Z, X, C, V, B
	DB	14,13,-1,-1,-1,-1	; N, M, ,, ., /, RShift
	DB	150,-1,' ',-1           ; *, Alt, Space, CL
					;--------- FUNCTIONS ---------
	DB	94,95,96,97,98,99	; F1 - F6
	DB	100,101,102,103,-1,-1	; F7 - F10, NL, SL
	DB	119,141,132,142,115,143 ; Home, Up, PgUp, -, Left, Pad5
	DB	116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
	DB	147,-1,-1,-1,137,138	; Del, SysReq, Undef, WT, F11, F12
;----------------------  TABLES FOR LOWER CASE	----------------------

K10	LABEL	BYTE
	DB	27,'12345'
	DB	'67890-'
	DB	'=',08,09,'qwe'
	DB	'rtyuio'
	DB	'p[]',0DH,-1,'a'        ; LETTERS, Return, Ctrl
	DB	'sdfghj'
	DB	"kl;'`",-1              ; LETTERS, L Shift
	DB	'\zxcvb'
	DB	'nm,./'
	DB	-1,'*',-1,' ',-1        ; R Shift,*, Alt, Space, CL

;------ LC TABLE SCAN
	DB	59,60,61,62,63		; BASE STATE OF F1 - F10
	DB	64,65,66,67,68
	DB	-1,-1			; NL, SL

;------ KEYPAD TABLE
K15	LABEL	BYTE
	DB	71,72,73,-1,75,-1	; BASE STATE OF KEYPAD KEYS
	DB	77,-1,79,80,81,82
	DB	83
	DB	-1,-1,'\',133,134        ; SysRq, Undef, WT, F11, F12

;----------------------  TABLES FOR UPPER CASE	----------------------

K11	LABEL	BYTE
	DB	27,'!@#$%'
	DB	'^&*()_'
	DB	'+',08,00,'QWE'
	DB	'RTYUIO'                ; LETTERS, Return, Ctrl
	DB	'P{}',0DH,-1,'A'
	DB	'SDFGHJ'
	DB	'KL:"~',-1              ; LETTERS, L Shift
	DB	'|ZXCVB'
	DB	'NM<>?'
	DB	-1,'*',-1,' ',-1        ; R Shift,*, Alt, Space, CL

;-----	UC TABLE SCAN
K12	LABEL	BYTE
	DB	84,85,86,87,88		; SHIFTED STATE OF F1 - F10
	DB	89,90,91,92,93
	DB	-1,-1			; NL, SL

;-----	NUM STATE TABLE
K14	LABEL	BYTE
	DB	'789-456+1230.'         ; NUMLOCK STATE OF KEYPAD KEYS
	DB	-1,-1,'|',135,136
CODE	ENDS
	END
